package com.amumu.drama.common.config;

import cn.hutool.extra.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author sunzhuang
 * @date 2024/8/14 14:47
 * @slogan 天下风云出我辈, 一入代码岁月催
 * @desc todo
 */
@Slf4j
@Component
public class ScheduledTaskUtil {
    private final static Lock lock = new ReentrantLock();

    private static ScheduledExecutorService scheduledExecutorService;

    @Bean
    public ScheduledExecutorService scheduledExecutorService() {
        return scheduledExecutorService = Executors.newScheduledThreadPool(3, (Runnable r) ->
                new Thread(new ThreadGroup("user-scheduled"), r, "scheduled-task-" + Thread.currentThread().getId(), 0));
    }

    public static void scheduledTask(Runnable r, long initialDelay, long period, TimeUnit timeUnit, String name) {
        if (scheduledExecutorService == null) {
            scheduledExecutorService = SpringUtil.getBean(ScheduledExecutorService.class);
            Runtime.getRuntime().addShutdownHook(new Thread(shutdownHook(scheduledExecutorService)));
        }
        scheduledExecutorService.scheduleAtFixedRate(() -> {
            if (lock.tryLock()) {
                try {
                    r.run();
                } finally {
                    lock.unlock();
                }
            } else {
                log.error("scheduledExecutorService 锁竞争失败：{}", name);
            }
        }, initialDelay, period, timeUnit);
    }


    public static Runnable shutdownHook(ScheduledExecutorService scheduledExecutorService) {
        return () -> {
            log.info("scheduledExecutorService shutting down...");
            scheduledExecutorService.shutdown();
            try {
                if (!scheduledExecutorService.awaitTermination(5, TimeUnit.SECONDS)) {
                    scheduledExecutorService.shutdownNow();
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                scheduledExecutorService.shutdownNow();
                log.error("关闭定时器线程池scheduledExecutorService异常：", e);
            }
        };
    }

    public static void main(String[] args) {
        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
        executorService.scheduleAtFixedRate(() -> {
            System.out.println("开始运行");
        }, 0, 1000, TimeUnit.MILLISECONDS);
    }
}
